//
//  CustomGridView.m
//  TAOVideo
//
//  Created by Lin Eidan on 13-8-7.
//  Copyright (c) 2013年 taomee. All rights reserved.
//

#import "CustomGridView.h"
#import "UIView+EidanSize.h"

#define OffsetYCanRemove        (self.height)
//#define OffsetYCanRemove        0

@implementation CustomGridView

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        [self setUp];
    }
    return self;
}

-(void)setUp{
    
    self.delegate=self;
    self.showsHorizontalScrollIndicator=NO;
    self.showsVerticalScrollIndicator=NO;
    
    self.mainGridView=[[UIView alloc] initWithFrame:CGRectMake(0, 0, self.width, self.height)];
    [self addSubview:self.mainGridView];
    
//    //这两个值，如果cell那边自己有空出来间隙，非瀑布流，是设置为0的。瀑布流的话，可以这边设置值，然后cell那边不留间隙，并且cell的xib中，图片和图片容器都要autoSizing，label要底部对齐。
//    self.ySpace=0;   //一列之中，cell与cell之间的上下间隙
    self.xSpace=0;   //多个竖列之间的左右间隙。
    
    //edit
    self.isInEditingMode = NO;
}

-(void)setGridViewLeft:(float)gridViewLeft{
    self.mainGridView.left=gridViewLeft;
    self.mainGridView.width=self.width-gridViewLeft;
}

-(void)resetWidthWithSubViews{
    self.mainGridView.width = self.width - self.mainGridView.left;
}

-(void)drawOtherViewBeforeGridView:(UIView *)otehrView andGridViewTop:(float )gridViewTop{
    if (!otehrView.superview) {
        [self addSubview:otehrView];
    }
    
    [self sendSubviewToBack:otehrView];
    self.mainGridView.top=gridViewTop;
    self.contentHeight=self.height+1;  //让其可以滚动
}

-(void)drawOtherViewInGridView:(UIView *)otehrView{
    if (!otehrView.superview  && otehrView.bottom <= self.mainGridView.height ) {  //在范围内才加。。
        [self.mainGridView addSubview:otehrView];
    }
}

-(CustomTableCell *)getCellWithIndexPath:(CustomIndexPath *)indexPath{
    
    if (indexPath.column >= self.visibleCellsArray.count) {
        return nil;
    }
    
    NSMutableArray *visibleCellsInTheColumnArray = [self.visibleCellsArray objectAtIndex:indexPath.column];
    for (CustomTableCell *cell in visibleCellsInTheColumnArray) {
        if (cell.indexPath.row == indexPath.row) {
            return cell;
        }
    }
    return nil;
}

//--------------------------------------------------------------------------编辑模式 start-----------------------------

//进入，退出编辑模式
-(void)customGridViewSetEdit:(BOOL)edit andAnimation:(BOOL)animation{
    if (edit == self.isInEditingMode) {  //本来就一样的
        return;
    }
    
    self.hasSelectedArray=[[NSMutableArray alloc] init];
    for (int i= 0; i<self.visibleCellsArray.count; i++) {
        NSMutableArray *visibleCellsInTheColumnArray = [self.visibleCellsArray objectAtIndex:i];
        for (int j = 0; j < visibleCellsInTheColumnArray.count; j++) {
            CustomTableCell *cell=[visibleCellsInTheColumnArray objectAtIndex:j];
            [cell customTableCellSetEdit:edit andAnimation:animation];
        }
    }
    
    self.isInEditingMode=edit;
}

-(void)handleCellIsInEditingMode:(CustomTableCell *)cell{
    [cell handleIsInEditingModeWithParent:self andIsInEditing:self.isInEditingMode];
}

-(BOOL)theCellIsInTheHasSelectedArray:(int )index{
    for (int i=0; i<self.hasSelectedArray.count; i++) {
        int  tempIndex=[[self.hasSelectedArray objectAtIndex:i] intValue];
        if (tempIndex == index) {
            return YES;
        }
    }
    return NO;
}

//全选
-(void)customGridViewSelectAllOrNot:(BOOL)isSelectedAll andArrayCount:(int )count{
    [self.hasSelectedArray removeAllObjects];
    if (isSelectedAll) {
        for (int i=0; i< count; i++) {
            [self.hasSelectedArray addObject:[NSNumber numberWithInt:i]];
        }
    }
    [self reloadData];
}


//--------------------------------------------------------------------------编辑模式 end-----------------------------

//--------------------------------------------------------------------------重用相关 start-----------------------------
- (CustomTableCell *)dequeueReusableCellWithIdentifier:(NSString *)identifier
{
    if (nil == identifier || 0 == identifier.length) {
        return nil;
    }
    
    NSMutableArray *reuseQueue = [self.reuseCellsDic objectForKey:identifier];
	if(reuseQueue && [reuseQueue isKindOfClass:[NSArray class]] && reuseQueue.count > 0) {
		CustomTableCell *cell = [reuseQueue lastObject];  //最后进去的，总是要最先出来。。
		[reuseQueue removeLastObject];  //取走了，就要移除掉。。。
		return cell;
	}
    return nil;
}

-(void)reloadData{
    
    //刷新数据了，把所有在可见数组的里面的cell，全部放进去重用数组，然后在下面的初始化中画出来
    if (self.visibleCellsArray && [self.visibleCellsArray count] > 0) {
        for (int i = 0; i < [self.visibleCellsArray count]; i++) {
            NSMutableArray *visibleCellsInTheColumnArray = [self.visibleCellsArray objectAtIndex:i];
            if (!visibleCellsInTheColumnArray || [visibleCellsInTheColumnArray count] == 0) continue;
            
            int visibleCellCount = [visibleCellsInTheColumnArray count];
            for (int j=0; j < visibleCellCount; j++) {
                CustomTableCell *cell = [visibleCellsInTheColumnArray objectAtIndex:j];
                [self addReusableCell:cell];
                if (cell.superview) [cell removeFromSuperview];
            }
        }
    }
    
    [self initialize];
    
}

- (void)addReusableCell:(CustomTableCell *)cell
{
    if (nil == cell.reuseIdentifier || 0 == cell.reuseIdentifier.length) {
        return ;
    }
    
    NSMutableArray *reuseQueue = [self.reuseCellsDic objectForKey:cell.reuseIdentifier];
    
    if(nil == reuseQueue) {
        reuseQueue = [NSMutableArray arrayWithObject:cell];
        [self.reuseCellsDic setObject:reuseQueue forKey:cell.reuseIdentifier];
    } else {
        [reuseQueue addObject:cell];
    }
}

-(void)initialize{
    self.numsOfColumn=[self.customGridViewdataSource numberOfColumnsInCustomGridView:self];
    self.reuseCellsDic=[NSMutableDictionary dictionaryWithCapacity:10];
    
    self.cellRectArray=[[NSMutableArray alloc] initWithCapacity:self.numsOfColumn];  //每次reload都清空
    self.visibleCellsArray=[[NSMutableArray alloc] initWithCapacity:self.numsOfColumn];
    
    float scrollHeight =0.0f;
    float columnOriginX=0.0+self.xSpace;
    for (int i= 0; i< self.numsOfColumn; i++) {
        NSMutableArray *cellsRectInTheColumnArray=[NSMutableArray array];
        NSUInteger numOfCellInTheColumn=[self.customGridViewdataSource customGridView:self numberOfRowsInColumn:i];
        
        CGFloat heightInTheColumnNow=0.0f;
        CGFloat columnWidth=[self.customGridViewdataSource customGridView:self widthOfColumn:i];
        for (int j=0; j< numOfCellInTheColumn; j++) {
            float topSpace = [self.customGridViewdataSource customGridView:self topSpaceForCellsAtIndexPath:[CustomIndexPath indexPathForRow:j inColumn:i]];
            CGFloat cellOriginY=heightInTheColumnNow + topSpace;
            CGFloat cellHeight=[self.customGridViewdataSource customGridView:self heightForCellsAtIndexPath:[CustomIndexPath indexPathForRow:j inColumn:i]];
            heightInTheColumnNow = cellHeight + cellOriginY;
            CGRect cellRect=CGRectMake(columnOriginX, cellOriginY, columnWidth, cellHeight);
            [cellsRectInTheColumnArray addObject:[NSValue valueWithCGRect:cellRect]];
        }
        columnOriginX+=columnWidth+self.xSpace;
        scrollHeight = (heightInTheColumnNow >= scrollHeight) ? heightInTheColumnNow :scrollHeight;  //因为每一列的高度都不一样，有可能下一列的高度比前一列高，所以取最高
        [self.cellRectArray addObject:cellsRectInTheColumnArray];
        [self.visibleCellsArray addObject:[NSMutableArray array]];   //可见数组先添加三个空元素。。
    }
    self.contentHeight=scrollHeight+self.mainGridView.top;
    
    if (self.contentHeight <= self.height) {   //保证内容高度小于高度的时候，让其可以滚动。。
        self.contentHeight = self.height+1;
    }
    
    self.mainGridView.height=scrollHeight;
    
    [self onScroll];
}

- (void)onScroll{
    for (int i = 0; i < self.numsOfColumn; i++) {
        NSUInteger basicVisibleRow = 0;
        CustomTableCell *cell = nil;
        CGRect cellRect;
        
        NSMutableArray *cellsRectInTheColumnArray = [self.cellRectArray objectAtIndex:i];   //每一列的位置数组
        NSMutableArray *visibleCellsInTheColumnArray = [self.visibleCellsArray objectAtIndex:i];  //第一次刚添加了3个,但是第一次里面的元素为空
        
        if ([visibleCellsInTheColumnArray count] == 0) {  //这里对每列只会执行一次,初始化的时候
            for (int j = 0; j < [cellsRectInTheColumnArray count]; j++ ) {
                cellRect = [[cellsRectInTheColumnArray objectAtIndex:j] CGRectValue];
                if (![self canRemoveCellForRect:cellRect]) {  //这个位置信息，是否在页面外，界面外为YES。,当在界面内时，，
                    CustomIndexPath *indexPath = [CustomIndexPath indexPathForRow:j inColumn:i];
                    basicVisibleRow = j; 
                    cell = [self.customGridViewdataSource customGridView:self cellAtIndexPath:indexPath]; //获得cell。。
                    cell.indexPath = indexPath;  //设置cell的行列信息。。
                    cell.frame = cellRect;
                    
                    [self handleCellIsInEditingMode:cell];
                    if (!cell.superview) [self.mainGridView addSubview:cell];  //第一次肯定会添加进去。。
                    
                    [visibleCellsInTheColumnArray insertObject:cell atIndex:0];  //这个数据，只添加每一行的第一个。。
                    break;
                }
            }
        } else {
            cell = [visibleCellsInTheColumnArray objectAtIndex:0];
            basicVisibleRow = cell.indexPath.row;
        }
        
        // Look back to load visible cells
        for (int j = basicVisibleRow - 1; j >= 0; j--) {
            cellRect = [[cellsRectInTheColumnArray objectAtIndex:j] CGRectValue];
            if (![self canRemoveCellForRect:cellRect]) {
                CustomIndexPath *indexPath = [CustomIndexPath indexPathForRow:j inColumn:i];  //获得行列信息。。
                if ([self containVisibleCellForIndexPath:indexPath]) {
                    continue ;
                }
                
                cell = [self.customGridViewdataSource customGridView:self cellAtIndexPath:indexPath];
                cell.indexPath = indexPath;
                cell.frame = cellRect;
                [self handleCellIsInEditingMode:cell];
                if (!cell.superview) [self.mainGridView addSubview:cell];
                [visibleCellsInTheColumnArray insertObject:cell atIndex:0];
            } else {
                break;
            }
        }
        
        // Look forward to load visible cells
        for (int j = basicVisibleRow + 1; j < [cellsRectInTheColumnArray count]; ++j) {
            cellRect = [[cellsRectInTheColumnArray objectAtIndex:j] CGRectValue];
            if (![self canRemoveCellForRect:cellRect]) {    //界面内的才添加。。。
                CustomIndexPath *indexPath = [CustomIndexPath indexPathForRow:j inColumn:i];
                if ([self containVisibleCellForIndexPath:indexPath]) {
                    //这个行列的位置虽然在页面内，但是如果它已经在页面上显示了，即已经在可见数组了，那么就应该跳过，不能再重复添加到数组和页面。。
                    continue ;   //停止当前循环，进行下一个循环
                }
                
                cell = [self.customGridViewdataSource customGridView:self cellAtIndexPath:indexPath]; // nil ?
                cell.indexPath = indexPath;
                cell.frame = cellRect;
                [self handleCellIsInEditingMode:cell];
                if (!cell.superview) [self.mainGridView addSubview:cell];
                
                [visibleCellsInTheColumnArray insertObject:cell atIndex:0]; //用insert，保证最下面的cell在数组的最前面
            }else {
                break;
            }
        }
        
        // Recycle invisible cells
        for (int j = 0; j < [visibleCellsInTheColumnArray count]; j++) {
            cell = [visibleCellsInTheColumnArray objectAtIndex:j];
            if ([self canRemoveCellForRect:cell.frame]) {  //每次滚动都随时检查，是否可以把该cell移除。。,移除后都被添加到reuseQueue这个数组里。。
//                NSLog(@"remove");
                [cell removeFromSuperview];
                [self addReusableCell:cell];
                [visibleCellsInTheColumnArray removeObject:cell];
                j--;
                //最后被移出去的，添加在reuse数组的最后面，然后，向下拉的时候，最后被移出去的总是最先进来，所以复用的时候总是取reuse的最后一个。。。
//                NSLog(@"remove: %d:::   %d",i,visibleCellsInTheColumnArray.count);
            }
        }
    }
}

//这个矩形是否在边界外
- (BOOL)canRemoveCellForRect:(CGRect)rect
{
    float offsetY = self.contentOffsetTop;
    float rectTrueY=rect.origin.y+self.mainGridView.top;
    //超出边界了，就可以移除。
    if (rectTrueY + rect.size.height + OffsetYCanRemove< offsetY || rectTrueY > (offsetY + self.height + OffsetYCanRemove)) {
        //加OffsetYCanRemove这个值，可以让scrllView在向上走的过程，位于比较底部的cell，不会那么快被移除出去。。
        //向下走也是同理。。
        return YES;
    }
    
    return NO;
}

//判断这个位置信息的cell是否在可见数组里。
- (BOOL)containVisibleCellForIndexPath:(CustomIndexPath *)indexPath
{
    NSArray *singleVisibleArray = [self.visibleCellsArray objectAtIndex:indexPath.column];
    for (int i = 0; i < [singleVisibleArray count]; i++) {
        CustomTableCell *cell = [singleVisibleArray objectAtIndex:i];
        if (cell.indexPath.row == indexPath.row) {
            return YES;
        }
    }
    return NO;
}
//--------------------------------------------------------------------------重用相关 end-----------------------------

-(void)scrollViewDidScroll:(UIScrollView *)scrollView{
    [self onScroll];
    if ([self.customGridViewdelegate respondsToSelector:@selector(customGridViewDidScroll:)]) {
        [self.customGridViewdelegate customGridViewDidScroll:self];
    }
}
-(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView{
    if ([self.customGridViewdelegate respondsToSelector:@selector(customGridViewDidEndDecelerating:)]) {
        [self.customGridViewdelegate customGridViewDidEndDecelerating:self];
    }
    
}
-(void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate{
    if ([self.customGridViewdelegate respondsToSelector:@selector(customGridViewDidEndDragging:willDecelerate:)]) {
        [self.customGridViewdelegate customGridViewDidEndDragging:self willDecelerate:decelerate];
    }
}

@end
